package linuxshell

import (
	"fmt"
	"strings"
)

type Arp struct {
	Super
	// Grep 附加查询
	Grep string
}

// ArpRes 返回值
type ArpRes struct {
	// Address IP
	Address string
	// Mac MAC 地址
	Mac string
	// 网卡名
	InterfaceName string
}

const (
	shellArp   = shellArpN
	shellArpN  = "arp -n"
	shellArpV  = "arp -v"
	shellArpVN = "arp -vn"
)

// RunArp run 'arp -n'
//
// Address        HWtype      HWaddress        Flags Mask       Iface
// 172.23.0.1      ether   02:42:37:cc:a1:19      C              eth0
// 172.23.0.2               (incomplete)                         eth0
func (*Arp) RunArp(grep ...string) ([]*ArpRes, error) {
	shell := shellArp

	// 解析指定查询
	if len(grep) > 0 {
		// eg: arp -n | grep 1.1.1.1
		for _, gv := range grep {
			shell = shell + fmt.Sprintf(shellGrepF, gv)
		}
	}

	//eg: res := "Address                  HWtype  HWaddress           Flags Mask            Iface\n172.23.0.1               ether   02:42:37:cc:a1:19   C                     eth0\n"
	res, err := execSingle(shell)
	if err != nil {
		return nil, err
	}

	var arpRes []*ArpRes
	if res == "" {
		return arpRes, nil
	}

	// parse line
	lines := strings.Split(res, "\n")
	lines = utils.ArrayRemoveEmptyStr(lines)
	if strings.HasPrefix(lines[0], "Address") {
		lines = lines[1:]
	}
	if len(lines) == 0 {
		return arpRes, nil
	}

	// parse column
	for _, line := range lines {
		vs := utils.RegexpSplitSpaces(line)

		var newArpRes ArpRes

		switch len(vs) {
		case 3:
			newArpRes.Address = vs[0]
			newArpRes.InterfaceName = vs[2]
		case 5:
			newArpRes.Address = vs[0]
			newArpRes.Mac = strings.ToUpper(vs[2])
			newArpRes.InterfaceName = vs[4]
		}

		arpRes = append(arpRes, &newArpRes)
	}
	return arpRes, nil
}
